package me.luraframework.gateway.auth.handler;

import com.google.common.collect.ImmutableMap;
import lombok.RequiredArgsConstructor;
import me.luraframework.commons.exception.AppException;
import me.luraframework.gateway.config.ApplicationProperties;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;

import static com.google.common.collect.ImmutableMap.of;
import static me.luraframework.gateway.exception.GatewayErrorCode.INVALID_TOKEN;

/**
 * @ description: RpcAuthService
 * @ author: Liu Ran
 * @ data: 7/13/23 19:29
 */
@Service
@RequiredArgsConstructor
public class RpcAuthHandler implements AuthHandler {

    private final WebClient.Builder builder;
    private final ApplicationProperties applicationProperties;


    @Override
    public AuthType getAuthType() {
        return AuthType.RPC;
    }

    @Override
    public String getToken(ServerWebExchange exchange) {
        return exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
    }

    @Override
    public Mono<Map<String, Object>> getUserContext(ServerWebExchange exchange) {
        return builder.build().post()
               .uri(applicationProperties.getAuth().getCheckUrl(), ImmutableMap.of("accessToken", getToken(exchange)))
               .contentType(MediaType.APPLICATION_JSON)
               .retrieve()
               .onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.error(new AppException(INVALID_TOKEN, of())))
               .onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.error(new AppException(INVALID_TOKEN, of())))
               .bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
               });
    }

    @Override
    public List<String> isWhitelist(ServerWebExchange exchange) {
        return null;
    }
}
